/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include <Context/当前默认操作数据.h>
#include <core/引擎配置.h>
#include "core/shader_line.h"

#include "数据创建销毁.h"
#include "节点编辑.h"


static S_Mesh* g圆圈线 = nullptr;
static S_Mesh* g包围盒 = nullptr;

static S_Mesh* g虚拟体边界线 = nullptr;
static S_Mesh* g虚拟体中心圆 = nullptr;
static S_Mesh* g虚拟体方向线 = nullptr;
static S_Mesh* g虚拟体发光面 = nullptr;

static S_Mesh* g单元素虚拟体网格 = nullptr;


static S_VkDrawIndirectCommand g虚拟体中心Indirect = {};
static S_VkDrawIndirectCommand g虚拟体中心_摄像机锥形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体中心_立方体Indirect = {};

static S_VkDrawIndirectCommand g虚拟体XY圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体YZ圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体XZ圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体XZ缩放圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体XYZ圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体方向Indirect = {};
static S_VkDrawIndirectCommand g虚拟体锥形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体边界线_并排线Indirect = {};
static S_VkDrawIndirectCommand g虚拟体边界线_XY四边形Indirect = {};

static S_VkDrawIndirectCommand g虚拟体四边Indirect = {};
static S_VkDrawIndirectCommand g虚拟体方向线_Z_Indirect = {};
static S_VkDrawIndirectCommand g虚拟体方向线_Y三角箭头_Indirect = {};


static S_VkDrawIndirectCommand gIndirect单元素虚拟体_XY圆 = {};
static S_VkDrawIndirectCommand gIndirect单元素虚拟体_XZ圆 = {};
static S_VkDrawIndirectCommand gIndirect单元素虚拟体_圆柱 = {};
static S_VkDrawIndirectCommand gIndirect单元素虚拟体_平面 = {};



static S_物体* g单虚拟体主物体 = nullptr;


static std::list<S_单色材质包>	g_骨骼材质包;
static std::list<S_材质*>		g_VecSphere质包;


S_VkDrawIndexedIndirectCommand S_虚拟体ID偏移::Indirect_交叉轴 = {};
S_VkDrawIndexedIndirectCommand S_虚拟体ID偏移::Indirect_方向轴 = {};
S_VkDrawIndexedIndirectCommand S_虚拟体ID偏移::Indirect_线框球 = {};


static S_VkDrawIndirectCommand Indirect_立方体 = {};


S_物体* f_node_初始化单虚拟体网格(S_设备环境& ctx) {
	if(!g包围盒) {
		g包围盒 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
		g包围盒->m_网格类型 = E_绘制方式::e_画线段;
		g包围盒->m_线宽 = 1.0;


		uint32 offset = 0;
		std::vector<S_VC> 顶点;
		//std::vector<vec2> 圆顶点(20);
		//f_graph_计算圆坐标XY({}, 中心园半径, 20, 圆顶点.data());
		//顶点.reserve(20);
		//for (auto& e : 圆顶点) {
		//	顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		//}

		//中心Indirect = { 20, 1, 0, 0 };
		//offset += 20;


		{
			Indirect_立方体 = { 24, 1, offset, 0 };
			Indirect_立方体.vertexCount = f_graph_立方体线段(顶点, {1,1,1}, {}, S_RGBA8UI{0,0,0,255});
			Indirect_立方体.firstVertex = offset;
			offset += Indirect_立方体.vertexCount;
		}

		{

		}


		f_surface_fill顶点数据(g包围盒, 顶点);
	}

	g单虚拟体主物体 = f_ob_创建物体(ctx, E_物体类型::t_虚拟体);
	f_ob_set数据槽数量(g单虚拟体主物体, 1);
	f_ob_set数据(g单虚拟体主物体, g包围盒);

	return g单虚拟体主物体;
}


void f_改变网格容器大小(std::vector<S_Mesh*>& meshs, uint32 num, S_设备环境& ctx, E_网格数据枚举 type) {
	uint32 原数量 = meshs.size();
	
	if (原数量 <= num) {
		meshs.reserve(num);
		for (uint32 i = 原数量; i < num; ++i) {
			auto* mesh = f_surface_创建网格对象(nullptr, ctx, type);
			meshs.push_back(mesh);
		}
	}
	else {
		for (;;) {
			f_surface_释放网格(meshs.back());
			meshs.pop_back();
			
			if (meshs.size() <= num || meshs.size() == 0) {
				break;
			}
		}
	}
}


static S_Mesh* f_创建圆圈线(S_设备环境& ctx) {
	static S_Mesh* 圆圈线 = nullptr;
	if (圆圈线) {
		圆圈线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);

		圆圈线->m_网格类型 = E_绘制方式::e_画线段;
		圆圈线->m_线宽 = 1.0;

		std::vector<S_VC> 顶点;
		std::vector<vec2> 圆顶点(20);
		f_graph_计算圆坐标XY({}, 0.2, 20, 圆顶点.data());
		顶点.reserve(20);
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		f_surface_fill顶点数据(圆圈线, 顶点);
		f_surface_计算包围盒(圆圈线);
	}
	
	return 圆圈线;
}



void f_node_网格绘制属性设置(S_物体* ob) {
	f_ob_set颜色2(ob, {}, ob->m_实例ID);
	f_ob_set颜色2(ob, S_节点UI主题::uic_模型面, ob->m_实例ID, 1);
	f_ob_set颜色2(ob, S_节点UI主题::uic_模型线, ob->m_实例ID, 2);

	if (ob->m_DataNum > 3) {
		f_ob_set颜色2(ob, S_节点UI主题::uic_模型线, ob->m_实例ID, 3);
	}

	auto 网格属性 = MeshProp_Init();
	网格属性.m_Activate = 0;
	for (uint32 i = 0; i < ob->m_DataNum; ++i) {
		f_mesh_set绘制属性(f_ob_fromMesh(ob, i), {});
		f_mesh_set间接绘制网格属性(f_ob_fromMesh(ob, i), 网格属性);
	}

	网格属性.m_Activate = 1;
	f_mesh_set间接绘制网格属性(f_ob_fromMesh(ob, 0), 网格属性);
}

void f_node_创建网格物体数据(S_物体* ob, S_设备环境& ctx) {
	f_ob_set数据槽数量(ob, 3);

	auto* mesh = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	S_Mesh* m1 = f_surface_创建实例(mesh);
	S_Mesh* m2 = f_surface_创建实例(mesh);

	f_ob_set数据(ob, mesh);
	f_ob_set数据(ob, m1, 1);
	f_ob_set数据(ob, m2, 2);

	f_ob_set材质(ob, f_NodeCtx_get基本光照描边材质(), 0);
	f_ob_set材质(ob, f_NodeCtx_get基本光照面材质(), 1);
	f_ob_set材质(ob, f_NodeCtx_get基本光照线材质(), 2);

	f_ob_set线宽(ob, 4.0, 0);
	f_NodeCtx_get默认场景()->f_add物体({ ob }, E_场景物体容器类型::e_集合);
	S_节点数据::m_全局物体set.insert(ob);


	f_mesh_gen间接绘制网格属性(mesh, 1);
	f_mesh_gen间接绘制网格属性(m1, 1);
	f_mesh_gen间接绘制网格属性(m2, 1);

	f_node_网格绘制属性设置(ob);

}

S_物体* f_node_网格节点创建物体数据(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_网格);

	f_node_创建网格物体数据(ob, ctx);
	
	ob->m_Name = L"几何体节点创建物体";
	return ob;
}

void f_node_构建多边形网格对象(S_设备环境& ctx, S_物体* ob) {
	f_ob_set数据槽数量(ob, 4);

	auto* mesh_面 = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	auto* mesh_点 = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	auto* mesh_线 = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);


	f_ob_set数据(ob, f_surface_创建实例(mesh_面), 0);
	f_ob_set数据(ob, mesh_面, 1);
	f_ob_set数据(ob, mesh_点, 2);
	f_ob_set数据(ob, mesh_线, 3);

	
	f_ob_set材质(ob, f_NodeCtx_get基本光照描边材质(), 0);
	f_ob_set材质(ob, f_NodeCtx_get基本光照面材质(), 1);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点点材质(), 2);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点线段材质(), 3);

	//f_mesh_gen间接绘制网格属性(mesh_面, 1);
	//f_mesh_gen间接绘制网格属性(mesh_点, 1);
	//f_mesh_gen间接绘制网格属性(mesh_线, 1);

	f_ob_set线宽(ob, 3.0, 0);

	
	f_node_网格绘制属性设置(ob);

	auto 网格属性 = MeshProp_Init();
	网格属性.m_Activate = 1;
	网格属性.m_Color = f_PackData4X8({ 0,0,0,255 });
	//网格属性.m_Intensity = 1;
	f_mesh_set间接绘制网格属性(f_ob_fromMesh(ob), 网格属性);

	ob->m_Name = L"几何体节点多边形物体";
}

S_物体* f_node_网格节点创建连续线物体数据(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_网格);
	ob->m_Name = L"连续线";
	f_ob_set数据槽数量(ob, 1);

	auto* mesh = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	f_ob_set数据(ob, mesh);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点连续线材质(), 0);

	f_ob_set线宽(ob, 1.0, 0);
	//f_NodeCtx_get默认场景()->f_add物体({ ob }, E_场景物体容器类型::e_集合);

	return ob;
}

S_物体* f_node_网格节点创建线段物体数据(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_网格);
	ob->m_Name = L"线段";
	f_ob_set数据槽数量(ob, 1);

	auto* mesh = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	f_ob_set数据(ob, mesh);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点线段材质(), 0);

	f_ob_set线宽(ob, 1.0, 0);
	//f_NodeCtx_get默认场景()->f_add物体({ ob }, E_场景物体容器类型::e_集合);

	return ob;
}

S_物体* f_node_网格节点创建点物体数据(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_网格);
	ob->m_Name = L"点";
	f_ob_set数据槽数量(ob, 1);

	auto* mesh = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	f_ob_set数据(ob, mesh);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点点材质(), 0);

	f_ob_set线宽(ob, 1.0, 0);
	//f_NodeCtx_get默认场景()->f_add物体({ ob }, E_场景物体容器类型::e_集合);

	return ob;
}

//S_物体* f_node_创建多边形物体数据(S_设备环境& ctx) {
//	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_多边形);
//	S_多边形* 多边形 = f_surface_创建多边形();
//	ob->m_UserData = 多边形;
//
//	ob->m_Name = L"多边形";
//	
//	f_node_构建多边形网格对象(ctx, ob);
//
//	f_NodeCtx_get默认场景()->f_add物体({ ob }, E_场景物体容器类型::e_集合);
//	return ob;
//}


void f_创建网格物体组(std::vector<S_物体*>& 物体, uint32 num, S_设备环境& ctx) {
	uint32 old_num = 物体.size();
	auto* r = 物体.data();

	r = 物体.data();
	for (uint32 i = num; i < old_num; ++i) {
		f_NodeCtx_get默认场景()->f_remove物体(r[i], E_场景物体容器类型::e_集合);
		f_ob_销毁物体(r[i]);
	}

	物体.resize(num);
	r = 物体.data();

	for (uint32 i = 0; i < num; ++i) {
		if (r[i] == 0) {
			//r[i] = f_ob_创建物体(E_物体类型::t_网格, 0, ctx);
			r[i] = f_node_网格节点创建物体数据(ctx);
		}
	}
}

void f_node_创建模型物体组(S_OBArray* 物体, uint32 num, E_物体类型 type, S_设备环境& ctx) {
	uint32 old_num = 物体->count;

	std::vector<S_物体*> 删除物体;
	for (uint32 i = num; i < old_num; ++i) {
		f_node_从主场景移除物体(物体->ptr_userData[i]);
		f_node_物体从全局容器移除(物体->ptr_userData[i]);

		//f_node_销毁模型网格(物体->ptr_userData[i]);
		删除物体.push_back(物体->ptr_userData[i]);
	}
	if(删除物体.size()) f_node_删除物体(删除物体);


	f_core_array_resize((S_Array*)物体, num);
	for (uint32 i = old_num; i < num; ++i) {
		switch (type) {
		case E_物体类型::t_网格:
			物体->ptr_userData[i] = f_node_网格节点创建物体数据(ctx);
			break;
		case E_物体类型::t_多边形:
			物体->ptr_userData[i] = f_ob_创建物体(ctx, E_物体类型::t_多边形);
			f_node_构建多边形网格对象(ctx, 物体->ptr_userData[i]);
			break;
		default:
			break;
		}
		
		f_node_物体加入全局容器中(物体->ptr_userData[i]);
		f_node_物体添加到主场景(物体->ptr_userData[i]);
	}
}

void f_销毁物体组(std::vector<S_物体*>& 物体) {
	uint32 num = 物体.size();
	auto** p1 = 物体.data();

	for (uint32 i = 0; i < num; ++i) {
		delete p1[i];
	}
}

void f_node_销毁模型网格(S_物体* ob) {
	switch (ob->m_Type) {
	case E_物体类型::t_网格:
		f_surface_释放网格(f_ob_fromMesh(ob, 0));
		f_surface_释放网格(f_ob_fromMesh(ob, 1));
		f_surface_释放网格(f_ob_fromMesh(ob, 2));
		break;
	case E_物体类型::t_多边形:
		f_surface_释放网格(f_ob_fromMesh(ob, 0));
		f_surface_释放网格(f_ob_fromMesh(ob, 1));
		f_surface_释放网格(f_ob_fromMesh(ob, 2));
		f_surface_释放网格(f_ob_fromMesh(ob, 3));
		break;
	default:
		break;
	}
}


void f_node_创建纹理组(S_TexArray* 纹理, uint32 num, S_设备环境& ctx) {
	uint32 old_num = 纹理->count;
	
	for (uint32 i = num; i < old_num; ++i) {
		f_scene_销毁纹理(f_NodeCtx_get默认场景(), 纹理->ptr_userData[i]);
	}

	f_core_array_resize((S_Array*)纹理, num);
	for (uint32 i = old_num; i < num; ++i) {
		纹理->ptr_userData[i] = f_scene_创建纹理(f_NodeCtx_get默认场景(), ctx, L"纹理集");
	}
}

void f_node_销毁纹理组(S_TexArray* 纹理) {
	
}




void f_node_物体节点创建物体数据_单色明暗(S_物体* ob) {
	f_ob_set数据槽数量(ob, 3);

	S_Mesh* mesh = (S_Mesh*)(ob->m_Data[0]);
	S_Mesh* m1 = f_surface_创建实例(mesh);
	S_Mesh* m2 = f_surface_创建实例(mesh);
	f_ob_set数据(ob, m1, 1);
	f_ob_set数据(ob, m2, 2);

	f_ob_set材质(ob, f_NodeCtx_get单色描边材质(), 0);
	f_ob_set材质(ob, f_NodeCtx_get单色平直面材质(), 1);
	f_ob_set材质(ob, f_NodeCtx_get单色线材质(), 2);
}

void f_node_将现有物体包装成骨骼网格(S_设备环境& ctx, S_物体* 骨骼, S_物体* 骨节) {
	S_单色材质包 包 = f_node_get骨骼可视材质(ctx);


	f_ob_set数据槽数量(骨骼, 2);
	S_Mesh* mesh = f_ob_fromMesh(骨骼, 0);
	S_Mesh* m1 = f_surface_创建实例(mesh, true);
	f_ob_set数据(骨骼, m1, 1);

	f_ob_set材质(骨骼, 包.m_描边, 0);
	f_ob_set材质(骨骼, 包.m_面, 1);

	mesh->m_深度控制 = { 0.00001f, 0.01f };
	m1->m_深度控制 = { 0.001f, 0.001f };

	if (骨节) {
		f_ob_set数据槽数量(骨节, 2);
		mesh = f_ob_fromMesh(骨节, 0);
		S_Mesh* m2 = f_surface_创建实例(mesh);
		f_ob_set数据(骨节, m2, 1);

		f_ob_set材质(骨节, 包.m_描边, 0);
		f_ob_set材质(骨节, 包.m_面, 1);

		mesh->m_深度控制 = { 0.00001f, 0.01f };
		m2->m_深度控制 = { 0.001f, 0.001f };
	}
	//f_ob_set实例数量(ob, 1);

}

S_物体* f_node_线网格节点创建物体数据(S_设备环境& ctx) {
	S_物体* obj = f_ob_创建物体(ctx, E_物体类型::t_网格);


	f_ob_set数据槽数量(obj, 3);
	auto* mesh = f_surface_创建网格对象(nullptr, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	f_ob_set数据(obj, mesh);


	S_Mesh* m1 = f_surface_创建实例(mesh);
	//S_Mesh* m2 = f_surface_创建实例(mesh);
	f_ob_set数据(obj, m1, 1);
	f_ob_set数据(obj, m1, 2);

	//描边材质网格必须要最前面
	f_ob_set材质(obj, f_NodeCtx_get线段描边材质(), 0);
	//线和面材质设定
	f_ob_set材质(obj, f_NodeCtx_get逐顶点线段材质(), 1);
	f_ob_set材质(obj, f_NodeCtx_get逐顶点线段材质(), 2);

	f_ob_set线宽(obj, 1.2, 0);
	//f_NodeCtx_get默认场景()->f_add物体(obj, E_场景物体容器类型::e_集合);


	obj->m_Name = L"几何体节点创建物体";

	return obj;
}

S_物体* f_node_创建虚拟体(S_设备环境& ctx, E_虚拟体类型 类型) {
	
	static S_Mesh* mesh = nullptr;
	static uint32 交叉轴顶点数量 = 0;
	static uint32 方向轴顶点数量 = 0;
	static uint32 线框球顶点数量 = 0;

	static uint32 交叉轴顶点索引数量 = 0;
	static uint32 方向轴顶点索引数量 = 0;
	static uint32 线框球顶点索引数量 = 0;

	if (!mesh) {
		mesh = f_surface_创建网格对象(ctx, E_网格数据枚举::e_Mesh_VULKAN);

		DEF_3Fs v;
		DEF_3Fs n;
		DEF_2Fs uv;
		DEF_Is index;
		std::vector<S_VkDrawIndirectCommand> Indirect;

		f_graph_构建交叉轴(v, n, uv, index);
		f_surface_push顶点(mesh, v);
		f_surface_push索引(mesh, index);
		//f_graph_添加间接绘制(Indirect, v, index);
		交叉轴顶点数量 = v.size();
		交叉轴顶点索引数量 = index.size();
		S_虚拟体ID偏移::Indirect_交叉轴.firstInstance = 0;
		S_虚拟体ID偏移::Indirect_交叉轴.instanceCount = 1;
		S_虚拟体ID偏移::Indirect_交叉轴.vertexOffset = 0;
		S_虚拟体ID偏移::Indirect_交叉轴.indexCount = 交叉轴顶点索引数量;
		S_虚拟体ID偏移::Indirect_交叉轴.firstIndex = 0;


		f_graph_构建方向轴(v, n, uv, index);
		//for (auto& e : index) e += 交叉轴顶点数量;
		f_surface_push顶点(mesh, v);
		f_surface_push索引(mesh, index);
		//f_graph_添加间接绘制(Indirect, v, index);
		方向轴顶点数量 = v.size();
		方向轴顶点索引数量 = index.size();
		S_虚拟体ID偏移::Indirect_方向轴.firstInstance = 0;
		S_虚拟体ID偏移::Indirect_方向轴.instanceCount = 1;
		S_虚拟体ID偏移::Indirect_方向轴.vertexOffset = 交叉轴顶点数量;
		S_虚拟体ID偏移::Indirect_方向轴.indexCount = 方向轴顶点索引数量;
		S_虚拟体ID偏移::Indirect_方向轴.firstIndex = 交叉轴顶点索引数量;


		f_graph_构建线框球(v, n, uv, index, 32);
		//for (auto& e : index) e += 交叉轴顶点数量 + 方向轴顶点数量;
		f_surface_push顶点(mesh, v);
		f_surface_push索引(mesh, index);
		//f_graph_添加间接绘制(Indirect, v, index);
		线框球顶点数量 = v.size();
		线框球顶点索引数量 = index.size();
		S_虚拟体ID偏移::Indirect_线框球.firstInstance = 0;
		S_虚拟体ID偏移::Indirect_线框球.instanceCount = 1;
		S_虚拟体ID偏移::Indirect_线框球.vertexOffset = 交叉轴顶点数量 + 方向轴顶点数量;
		S_虚拟体ID偏移::Indirect_线框球.indexCount = 线框球顶点索引数量;
		S_虚拟体ID偏移::Indirect_线框球.firstIndex = 交叉轴顶点索引数量 + 方向轴顶点索引数量;

		mesh->m_线宽 = 4.0;
	}



	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_虚拟体);
	f_ob_set数据槽数量(ob, 1);
	f_ob_set数据(ob, mesh);
	f_ob_set材质(ob, f_NodeCtx_get单色线段材质());

	//f_ob_填充间接绘制(ob, { indirect });
	return ob;
}

S_物体* f_node_创建虚线(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_线段);
	f_ob_set数据槽数量(ob, 1);

	S_Mesh* mesh = f_surface_创建网格对象(ctx, E_网格数据枚举::e_Mesh_VULKAN);
	f_ob_set数据(ob, mesh);
	f_ob_set材质(ob, f_NodeCtx_get单色连续线材质());

	return ob;
}

S_物体* f_node_创建骨架物体(S_设备环境& ctx) {

	S_物体* 骨架对象 = f_ob_创建物体(ctx, E_物体类型::t_物体包);
	//S_物体* 虚线 = f_node_创建虚线(ctx);
	{
		S_物体* 骨骼物体 = f_ob_创建物体(ctx, E_物体类型::t_骨架);
		S_物体* 骨节物体 = f_ob_创建物体(ctx, E_物体类型::t_网格);

		f_ob_create骨骼虚拟体网格(ctx, 骨骼物体, 骨节物体);
		f_node_将现有物体包装成骨骼网格(ctx, 骨骼物体, 骨节物体);

		f_ob_add子物体(骨架对象, 骨骼物体);
		f_ob_add子物体(骨架对象, 骨节物体);
		//f_ob_add子物体(m_骨骼对象, m_虚线);

		S_物体* 根骨节 = f_ob_创建物体实例(nullptr, 0);
		根骨节->m_UserData = 骨骼物体;
		f_ob_add子物体(骨节物体, 根骨节);
		
		骨骼物体->m_UserData = 根骨节;

	}

	return 骨架对象;
}

S_物体* f_node_创建骨头物体(S_设备环境& ctx) {
	S_物体* 骨头 = f_ob_创建骨骼(nullptr);

	S_物体* 骨节 = f_ob_创建物体实例(nullptr, 0);
	骨节->f_set位置(DEF_骨骼朝向, 0);
	骨头->m_UserData = 骨节;

	return 骨头;
}

S_物体* f_node_创建包围盒虚拟体(S_设备环境& ctx) {
	S_MeshTranformProp 线属性 = MeshProp_Init();
	线属性.m_TransformMode = 0;
	S_材质* material = f_NodeCtx_get单虚拟体材质(ctx);

	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_网格);
	
	f_ob_set数据槽数量(ob, 1);
	f_ob_set数据(ob, g包围盒);
	f_ob_set材质(ob, material);

	//f_material_set线属性(material, 0, 线属性);
	return ob;
}


/*S_物体* f_node_创建点光源虚拟网格(S_设备环境& ctx) {
	
	static S_Mesh* 外圆圈线 = nullptr;
	static S_Mesh* 竖向线 = nullptr;
	

	if (!g圆圈线) {
		g圆圈线 = f_创建圆圈线(ctx);

		std::vector<S_VC> 顶点;
		std::vector<vec2> 圆顶点(20);
		
		外圆圈线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
		外圆圈线->m_网格类型 = E_绘制方式::e_画线段;
		外圆圈线->m_线宽 = 0.1;

		圆顶点.resize(40);
		顶点.clear();
		f_graph_计算圆坐标XY({}, 1.0, 40, 圆顶点.data());
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,128}) });
		}
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, 0, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,128}) });
		}
		for (auto& e : 圆顶点) {
			顶点.push_back({ {0, e.y, e.x}, f_PackData4X8(S_RGBA8UI{0,0,0,128}) });
		}
		f_surface_fill顶点数据(外圆圈线, 顶点);
		f_surface_计算包围盒(外圆圈线);
	}

	if (!竖向线) {
		竖向线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
		竖向线->m_网格类型 = E_绘制方式::e_画线段;
		竖向线->m_线宽 = 0.7;

		std::vector<S_VC> 顶点;
		顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,-1,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		f_surface_fill顶点数据(竖向线, 顶点);
		f_surface_计算包围盒(竖向线);
		
	}

	static S_物体* 点光源主物体 = nullptr;
	if (!点光源主物体) {
		点光源主物体 = f_ob_创建物体(ctx, E_物体类型::t_包);

		f_ob_set数据槽数量(点光源主物体, 3);

		f_ob_set数据(点光源主物体, g圆圈线, 0);
		f_ob_set数据(点光源主物体, 外圆圈线, 1);
		f_ob_set数据(点光源主物体, 竖向线, 2);
		f_ob_set材质(点光源主物体, f_NodeCtx_get逐顶点线段材质(true), 0);
		f_ob_set材质(点光源主物体, f_NodeCtx_get逐顶点线段材质(), 1);
		f_ob_set材质(点光源主物体, f_NodeCtx_get逐顶点线段材质(), 2);

		

		f_NodeCtx_get默认场景()->f_add物体({ 点光源主物体 }, E_场景物体容器类型::e_集合);
	}


	S_LinesProp 线属性;
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 0;
	线属性.m_Scale = 1;
	线属性.m_TransformMode = 1;

	S_物体* m_Ob = f_ob_创建物体(ctx, E_物体类型::t_点光源);
	m_Ob->m_ID = f_scene_渲染器分配点光源内存(f_NodeCtx_get默认场景());

	f_material_add线属性(f_NodeCtx_get逐顶点线段材质(true), 1);
	f_material_set线属性(f_NodeCtx_get逐顶点线段材质(true), m_Ob->m_ID, 线属性);

	线属性.m_TransformMode = 0;
	f_material_add线属性(f_NodeCtx_get逐顶点线段材质(), 1);
	f_material_set线属性(f_NodeCtx_get逐顶点线段材质(), m_Ob->m_ID, 线属性);
	f_ob_add子物体(点光源主物体, m_Ob);

	return m_Ob;
}

S_物体* f_node_创建平行光虚拟网格(S_设备环境& ctx) {
	S_Mesh* 圆圈线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	圆圈线->m_网格类型 = E_绘制方式::e_画线段;

	S_Mesh* 方向线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	方向线->m_网格类型 = E_绘制方式::e_画线段;


	std::vector<S_VC> 顶点;
	顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
	顶点.push_back({ {0,-1,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
	f_surface_fill顶点数据(方向线, 顶点);
	//f_graph_构建骨骼锥体(size, V, N, I);
	顶点.clear();

	std::vector<vec2> 圆顶点(20);
	f_graph_计算圆坐标XY({}, 0.2, 20, 圆顶点.data());
	顶点.reserve(20);
	for (auto& e : 圆顶点) {
		顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
	}
	f_surface_fill顶点数据(圆圈线, 顶点);

	
	
	圆圈线->m_线宽 = 1.0;
	方向线->m_线宽 = 3.0;
	

	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_线段);
	f_ob_创建矩阵(ob, ctx);
	f_ob_set数据槽数量(ob, 2);
	f_ob_set数据(ob, 圆圈线, 0);
	f_ob_set数据(ob, 方向线, 1);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点线段材质(), 0);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点线段材质(), 1);
	return ob;
}*/




static S_物体* g虚拟体主物体 = nullptr;
static S_Mesh* 边界线 = nullptr;
static S_Mesh* 中心圆 = nullptr;
static S_Mesh* 方向线 = nullptr;
static S_Mesh* 发光面 = nullptr;

static uint32 g区域光InstanceID = 0;
//static uint32 g圆形区域光InstanceID = 0;
static S_VkDrawIndirectCommand 中心Indirect = {};
static S_VkDrawIndirectCommand 中心_摄像机锥形Indirect = {};
static S_VkDrawIndirectCommand 中心_立方体Indirect = {};

static S_VkDrawIndirectCommand XY圆形Indirect = {};
static S_VkDrawIndirectCommand YZ圆形Indirect = {};
static S_VkDrawIndirectCommand XYZ圆形Indirect = {};
static S_VkDrawIndirectCommand 方向Indirect = {};
static S_VkDrawIndirectCommand 锥形Indirect = {};
static S_VkDrawIndirectCommand 边界线_并排线Indirect = {};
static S_VkDrawIndirectCommand 边界线_XY四边形Indirect = {};
static S_VkDrawIndirectCommand 边界线_链接线Indirect = {};

static S_VkDrawIndirectCommand 四边Indirect = {};
static S_VkDrawIndirectCommand XZ圆形Indirect = {};
static S_VkDrawIndirectCommand XZ缩放圆形Indirect = {};

static S_VkDrawIndirectCommand 方向线_Z_Indirect = {};
static S_VkDrawIndirectCommand 方向线_Y三角箭头_Indirect = {};
static S_VkDrawIndirectCommand 方向线_链接线_Indirect = {};

S_物体* f_node_创建虚拟体网格物体(S_设备环境& ctx, E_物体类型 类型) {
	
	const float 中心园半径 = 0.2;
	if (!中心圆) {
		//中心圆 = f_创建圆圈线(ctx);
		中心圆 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);

		中心圆->m_网格类型 = E_绘制方式::e_画线段;
		中心圆->m_线宽 = 1.0;


		uint32 offset = 0;
		std::vector<S_VC> 顶点;
		std::vector<vec2> 圆顶点(20);
		f_graph_计算圆坐标XY({}, 中心园半径, 20, 圆顶点.data());
		顶点.reserve(20);
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		
		中心Indirect = { 20, 1, 0, 0 };
		offset += 20;



		{
			//float32 r = tan(M_角度转弧度(1) * 0.5);
			float32 r = 0.5;
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });


			顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			中心_摄像机锥形Indirect = { 16, 1, offset, 0 };
			offset += 中心_摄像机锥形Indirect.vertexCount;
		}
		
		{
			中心_立方体Indirect = { 24, 1, offset, 0 };
			中心_立方体Indirect.vertexCount = f_graph_立方体线段(顶点, {1,1,1}, {}, S_RGBA8UI{0,0,0,255});
			中心_立方体Indirect.firstVertex = offset;
			offset += 中心_立方体Indirect.vertexCount;
		}


		offset = f_surface_fill顶点数据(中心圆, 顶点);
		f_surface_计算包围盒(中心圆);

		中心Indirect.firstVertex += offset;
		中心_摄像机锥形Indirect.firstVertex += offset;
		中心_立方体Indirect.firstVertex += offset;
	}


	
	if (!边界线) {
		
		边界线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
		边界线->m_网格类型 = E_绘制方式::e_画连续线;
		边界线->m_线宽 = 1.0;


		uint32 offset = 0;
		std::vector<S_VC> 顶点;
		顶点.push_back({ {-1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

		顶点.push_back({ {1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

		顶点.push_back({ {1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

		顶点.push_back({ {-1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		四边Indirect = { 8, 1, offset, 0 };
		offset += 8;


		


		uint32 圆细分数量 = 128;
		std::vector<vec2> 圆顶点(圆细分数量);
		f_graph_计算圆坐标XY({}, 1.0, 圆细分数量, 圆顶点.data());
		XYZ圆形Indirect = { 圆细分数量, 1, offset, 0 };

		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		XY圆形Indirect = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;

		for (auto& e : 圆顶点) {
			顶点.push_back({ {0, e.y, e.x}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		YZ圆形Indirect = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;
		
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, 0, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		XZ圆形Indirect = { 圆细分数量, 1, offset, 0 };

		XYZ圆形Indirect.vertexCount = 圆细分数量 * 3;
		offset += 圆细分数量;



		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, -2, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		XZ缩放圆形Indirect = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;

		vec3 平行光线条1 = { 中心园半径 * sin(M_PI * 0.5 * 0.2), -中心园半径 * cos(M_PI * 0.5 * 0.2), 0 };
		vec3 平行光线条2 = { 中心园半径 * sin(M_PI * 0.5 * 0.5), -中心园半径 * cos(M_PI * 0.5 * 0.5), 0 };
		vec3 平行光线条3 = { 中心园半径 * sin(M_PI * 0.5), -中心园半径 * cos(M_PI * 0.5), 0 };
		
		顶点.push_back({ 平行光线条1, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {平行光线条1.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ 平行光线条2, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {平行光线条2.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ 平行光线条3, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {平行光线条3.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		
		顶点.push_back({ {-平行光线条1.x, 平行光线条1.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条1.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条2.x, 平行光线条2.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条2.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条3.x, 平行光线条3.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条3.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		边界线_并排线Indirect = { 12, 1, offset , 0 };
		offset += 12;



		顶点.push_back({ {-1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		边界线_XY四边形Indirect = { 8, 1, offset , 0 };
		offset += 8;


		顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 1, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		边界线_链接线Indirect = { 2, 1, offset , 0 };
		offset += 2;


		offset = f_surface_fill顶点数据(边界线, 顶点);
		f_surface_计算包围盒(边界线);
		
		四边Indirect.firstVertex += offset;
		XY圆形Indirect.firstVertex += offset;
		YZ圆形Indirect.firstVertex += offset;
		XZ圆形Indirect.firstVertex += offset;
		XYZ圆形Indirect.firstVertex += offset;
		XZ缩放圆形Indirect.firstVertex += offset;
		边界线_并排线Indirect.firstVertex += offset;
		边界线_XY四边形Indirect.firstVertex += offset;
	}

	if (!方向线) {
		方向线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
		方向线->m_网格类型 = E_绘制方式::e_画线段;
		方向线->m_线宽 = 1.0;

		uint32 offset = 0;

		std::vector<S_VC> 顶点;
		顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,-1,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		方向Indirect = { 2, 1, 0, 0 };
		offset += 2;

		顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, -2, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, -2, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		锥形Indirect = { 4, 1, offset, 0 };
		offset += 4;

		顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,0,1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		方向线_Z_Indirect = { 2, 1, offset, 0 };
		offset += 2;

		顶点.push_back({ {-0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,0.3,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,0.3,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		方向线_Y三角箭头_Indirect = { 6, 1, offset, 0 };
		offset += 6;


		顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 1, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		方向线_链接线_Indirect = { 2, 1, offset , 0 };
		offset += 2;
		//方向线_方体链接_Indirect = { 24, 1, offset, 0 };
		//方向线_方体链接_Indirect.vertexCount = f_graph_立方体线段(顶点, { 1,1,1 }, {}, S_RGBA8UI{ 0,0,0,255 });
		//方向线_方体链接_Indirect = { 6, 1, offset, 0 };
		//offset += 6;


		offset = f_surface_fill顶点数据(方向线, 顶点);
		f_surface_计算包围盒(方向线);

		方向Indirect.firstVertex += offset;
		锥形Indirect.firstVertex += offset;
		方向线_Z_Indirect.firstVertex += offset;
		方向线_Y三角箭头_Indirect.firstVertex += offset;
		方向线_链接线_Indirect.firstVertex += offset;
	}

	
	
	

	if (!g虚拟体主物体) {
		g虚拟体主物体 = f_ob_创建物体(ctx, E_物体类型::t_包);
		
		f_ob_set数据槽数量(g虚拟体主物体, 3);

		f_ob_set数据(g虚拟体主物体, 中心圆, 0);
		f_ob_set数据(g虚拟体主物体, 边界线, 1);
		f_ob_set数据(g虚拟体主物体, 方向线, 2);

		f_ob_set材质(g虚拟体主物体, f_NodeCtx_get灯光模型中心圆材质(中心圆->m_Ctx), 0);
		f_ob_set材质(g虚拟体主物体, f_NodeCtx_get灯光模型范围线材质(边界线->m_Ctx), 1);
		f_ob_set材质(g虚拟体主物体, f_NodeCtx_get灯光模型方向线材质(方向线->m_Ctx), 2);
		

		f_mesh_gen间接绘制网格属性(中心圆, 1);
		f_mesh_gen间接绘制网格属性(边界线, 1);
		f_mesh_gen间接绘制网格属性(方向线, 1);

		f_node_网格绘制属性设置(g虚拟体主物体);
		
		f_NodeCtx_get默认场景()->f_add物体({ g虚拟体主物体 }, E_场景物体容器类型::e_集合);
		S_节点数据::m_全局物体set.insert(g虚拟体主物体);
		g虚拟体主物体->m_根实例 = true;
	}

	
	//return nullptr;
	S_物体* m_Ob = f_ob_创建物体(ctx, 类型);
	f_ob_add子物体(g虚拟体主物体, m_Ob);

	if (g虚拟体主物体->m_变换矩阵.m_Mem.m_大小 < g虚拟体主物体->m_子物体.size()) {
		f_ob_添加矩阵(g虚拟体主物体);
	}
	//f_buf_push_back<Mat44f>(g虚拟体主物体->m_变换矩阵, { {} });
	

	S_MeshTranformProp 线属性 = MeshProp_Init();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	//f_mesh_set网格属性(边界线, 线属性, m_Ob->m_实例ID);
	//f_mesh_set网格属性(方向线, 线属性, m_Ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	//f_material_set线属性(f_NodeCtx_get灯光模型中心圆材质(中心圆->m_Ctx), m_Ob->m_实例ID, 线属性);
	//f_mesh_set网格属性(中心圆, 线属性, m_Ob->m_实例ID);
	

	switch (类型) {
	case E_物体类型::t_平行光: {
		m_Ob->m_ID = f_scene_渲染器分配平行光内存(f_NodeCtx_get默认场景());
		f_node_创建平行光虚拟体(m_Ob);
		break;
	}
	case E_物体类型::t_点光源: {
		m_Ob->m_ID = f_scene_渲染器分配点光源内存(f_NodeCtx_get默认场景());
		f_node_创建点光源虚拟体(m_Ob);
		break;
	}
	case E_物体类型::t_区域光 : {
		m_Ob->m_ID = f_scene_渲染器分配区域光内存(f_NodeCtx_get默认场景());
		f_node_创建区域光虚拟体(m_Ob);
		break;
	}
	case E_物体类型::t_聚光灯: {
		m_Ob->m_ID = f_scene_渲染器分配聚光灯内存(f_NodeCtx_get默认场景());
		f_node_创建聚光灯虚拟体(m_Ob);
		break;
	}
	case E_物体类型::t_虚拟体: {
		f_node_创建摄像机虚拟体(m_Ob);
		break;
	}
	}

	return m_Ob;
}

S_物体* f_node_创建虚拟体(S_设备环境& ctx) {
	return nullptr;
}

void f_node_释放虚拟体网格() {
	if(g虚拟体主物体) f_ob_clear子物体(g虚拟体主物体);
}


S_物体* f_node_get多元素虚拟体根物体(S_设备环境& ctx) {
	static S_物体* g虚拟体根物体 = nullptr;
	if (!g虚拟体根物体) {
		
		const float 中心园半径 = 0.2;
		if (!g虚拟体中心圆) {
			g虚拟体中心圆 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);

			g虚拟体中心圆->m_网格类型 = E_绘制方式::e_画线段;
			g虚拟体中心圆->m_线宽 = 1.0;


			uint32 offset = 0;
			std::vector<S_VC> 顶点;
			std::vector<vec2> 圆顶点(20);
			f_graph_计算圆坐标XY({}, 中心园半径, 20, 圆顶点.data());
			顶点.reserve(20);
			for (auto& e : 圆顶点) {
				顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}

			g虚拟体中心Indirect = { 20, 1, 0, 0 };
			offset += 20;



			{
				//float32 r = tan(M_角度转弧度(1) * 0.5);
				float32 r = 0.5;
				顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });


				顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

				顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

				顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

				顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

				g虚拟体中心_摄像机锥形Indirect = { 16, 1, offset, 0 };
				offset += g虚拟体中心_摄像机锥形Indirect.vertexCount;
			}

			{
				g虚拟体中心_立方体Indirect = { 24, 1, offset, 0 };
				g虚拟体中心_立方体Indirect.vertexCount = f_graph_立方体线段(顶点, {1,1,1}, {}, S_RGBA8UI{0,0,0,255});
				g虚拟体中心_立方体Indirect.firstVertex = offset;
				offset += g虚拟体中心_立方体Indirect.vertexCount;
			}


			offset = f_surface_fill顶点数据(g虚拟体中心圆, 顶点);
			f_surface_计算包围盒(g虚拟体中心圆);

			g虚拟体中心Indirect.firstVertex += offset;
			g虚拟体中心_摄像机锥形Indirect.firstVertex += offset;
			g虚拟体中心_立方体Indirect.firstVertex += offset;
		}



		if (!g虚拟体边界线) {

			g虚拟体边界线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
			g虚拟体边界线->m_网格类型 = E_绘制方式::e_画连续线;
			g虚拟体边界线->m_线宽 = 1.0;


			uint32 offset = 0;
			std::vector<S_VC> 顶点;
			顶点.push_back({ {-1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {-1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体四边Indirect = { 8, 1, offset, 0 };
			offset += 8;





			uint32 圆细分数量 = 128;
			std::vector<vec2> 圆顶点(圆细分数量);
			f_graph_计算圆坐标XY({}, 1.0, 圆细分数量, 圆顶点.data());
			g虚拟体XYZ圆形Indirect = { 圆细分数量, 1, offset, 0 };

			for (auto& e : 圆顶点) {
				顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}
			g虚拟体XY圆形Indirect = { 圆细分数量, 1, offset, 0 };
			offset += 圆细分数量;

			for (auto& e : 圆顶点) {
				顶点.push_back({ {0, e.y, e.x}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}
			g虚拟体YZ圆形Indirect = { 圆细分数量, 1, offset, 0 };
			offset += 圆细分数量;

			for (auto& e : 圆顶点) {
				顶点.push_back({ {e.x, 0, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}
			g虚拟体XZ圆形Indirect = { 圆细分数量, 1, offset, 0 };

			g虚拟体XYZ圆形Indirect.vertexCount = 圆细分数量 * 3;
			offset += 圆细分数量;



			for (auto& e : 圆顶点) {
				顶点.push_back({ {e.x, -2, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}
			g虚拟体XZ缩放圆形Indirect = { 圆细分数量, 1, offset, 0 };
			offset += 圆细分数量;

			vec3 平行光线条1 = { 中心园半径 * sin(M_PI * 0.5 * 0.2), -中心园半径 * cos(M_PI * 0.5 * 0.2), 0 };
			vec3 平行光线条2 = { 中心园半径 * sin(M_PI * 0.5 * 0.5), -中心园半径 * cos(M_PI * 0.5 * 0.5), 0 };
			vec3 平行光线条3 = { 中心园半径 * sin(M_PI * 0.5), -中心园半径 * cos(M_PI * 0.5), 0 };

			顶点.push_back({ 平行光线条1, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {平行光线条1.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ 平行光线条2, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {平行光线条2.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ 平行光线条3, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {平行光线条3.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });

			顶点.push_back({ {-平行光线条1.x, 平行光线条1.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条1.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条2.x, 平行光线条2.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条2.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条3.x, 平行光线条3.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条3.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			g虚拟体边界线_并排线Indirect = { 12, 1, offset , 0 };
			offset += 12;



			顶点.push_back({ {-1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体边界线_XY四边形Indirect = { 8, 1, offset , 0 };
			offset += 8;



			offset = f_surface_fill顶点数据(g虚拟体边界线, 顶点);
			f_surface_计算包围盒(g虚拟体边界线);

			g虚拟体四边Indirect.firstVertex += offset;
			g虚拟体XY圆形Indirect.firstVertex += offset;
			g虚拟体YZ圆形Indirect.firstVertex += offset;
			g虚拟体XZ圆形Indirect.firstVertex += offset;
			g虚拟体XYZ圆形Indirect.firstVertex += offset;
			g虚拟体XZ缩放圆形Indirect.firstVertex += offset;
			g虚拟体边界线_并排线Indirect.firstVertex += offset;
			g虚拟体边界线_XY四边形Indirect.firstVertex += offset;
		}

		if (!g虚拟体方向线) {
			g虚拟体方向线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
			g虚拟体方向线->m_网格类型 = E_绘制方式::e_画线段;
			g虚拟体方向线->m_线宽 = 1.0;

			uint32 offset = 0;

			std::vector<S_VC> 顶点;
			顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0,-1,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体方向Indirect = { 2, 1, 0, 0 };
			offset += 2;

			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, -2, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, -2, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体锥形Indirect = { 4, 1, offset, 0 };
			offset += 4;

			顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0,0,1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体方向线_Z_Indirect = { 2, 1, offset, 0 };
			offset += 2;

			顶点.push_back({ {-0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0,0.3,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0,0.3,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体方向线_Y三角箭头_Indirect = { 6, 1, offset, 0 };
			offset += 6;


			offset = f_surface_fill顶点数据(g虚拟体方向线, 顶点);
			f_surface_计算包围盒(g虚拟体方向线);

			g虚拟体方向Indirect.firstVertex += offset;
			g虚拟体锥形Indirect.firstVertex += offset;
			g虚拟体方向线_Z_Indirect.firstVertex += offset;
			g虚拟体方向线_Y三角箭头_Indirect.firstVertex += offset;
		}




		{
			g虚拟体根物体 = f_ob_创建物体(ctx, E_物体类型::t_包);
			f_ob_创建矩阵(g虚拟体根物体, ctx);

			f_ob_set数据槽数量(g虚拟体根物体, 3);

			f_ob_set数据(g虚拟体根物体, g虚拟体中心圆, 0);
			f_ob_set数据(g虚拟体根物体, g虚拟体边界线, 1);
			f_ob_set数据(g虚拟体根物体, g虚拟体方向线, 2);

			f_ob_set材质(g虚拟体根物体, f_NodeCtx_get虚拟体中心圆材质(g虚拟体中心圆->m_Ctx), 0);
			f_ob_set材质(g虚拟体根物体, f_NodeCtx_get虚拟体范围线材质(g虚拟体边界线->m_Ctx), 1);
			f_ob_set材质(g虚拟体根物体, f_NodeCtx_get虚拟体方向线材质(g虚拟体方向线->m_Ctx), 2);


			//S_MeshDrawProp 中心圆Prop;
			//中心圆Prop.TranformPropOffset = g虚拟体中心圆->m_网格属性.m_Mem.m_偏移;
			//f_mesh_set绘制属性(g虚拟体中心圆, 中心圆Prop);
			//S_MeshDrawProp 边界线Prop;
			//边界线Prop.TranformPropOffset = g虚拟体边界线->m_网格属性.m_Mem.m_偏移;
			//f_mesh_set绘制属性(g虚拟体边界线, 边界线Prop);
			//S_MeshDrawProp 方向线Prop;
			//方向线Prop.TranformPropOffset = g虚拟体方向线->m_网格属性.m_Mem.m_偏移;
			//f_mesh_set绘制属性(g虚拟体方向线, 方向线Prop);
			f_surface_add间接绘制(g虚拟体中心圆, S_VkDrawIndirectCommand{});
			f_surface_add间接绘制(g虚拟体边界线, S_VkDrawIndirectCommand{});
			f_surface_add间接绘制(g虚拟体方向线, S_VkDrawIndirectCommand{});

			f_node_物体添加到主场景(g虚拟体根物体);
		}
		
	}
	return g虚拟体根物体;
}

S_物体* f_node_get单元素虚拟体根物体(S_设备环境* ctx) {
	static S_物体* g虚拟体根物体 = nullptr;
	if (!g虚拟体根物体 && ctx) {

		uint32 offset = 0;
		uint32 圆细分数量 = 128;
		std::vector<S_VC> 顶点;
		std::vector<vec2> 圆顶点(圆细分数量);
		
		f_graph_计算圆坐标XY({}, 0.5, 圆细分数量, 圆顶点.data());
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		gIndirect单元素虚拟体_XY圆 = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;

		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, 0, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		gIndirect单元素虚拟体_XZ圆 = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;

		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, 0.5, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, -0.5, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		顶点.push_back({ {-0.5f, -0.5, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.5f, 0.5, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5f, -0.5, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5f, 0.5, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

		顶点.push_back({ {0, -0.5, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0, 0.5, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0, -0.5, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0, 0.5, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		gIndirect单元素虚拟体_圆柱 = { 圆细分数量*2+8, 1, offset, 0 };
		offset += gIndirect单元素虚拟体_圆柱.vertexCount;



		顶点.push_back({ {-0.5, 0, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5,  0, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.5, 0, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5,  0, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.5, 0, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.5, 0, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5, 0, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5,  0, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		gIndirect单元素虚拟体_平面 = { 8, 1, offset, 0 };
		offset += gIndirect单元素虚拟体_平面.vertexCount;


		g单元素虚拟体网格 = f_surface_创建网格对象(0, *ctx, E_网格数据枚举::e_Mesh_VULKAN);
		g单元素虚拟体网格->m_网格类型 = E_绘制方式::e_画线段;
		offset = f_surface_fill顶点数据(g单元素虚拟体网格, 顶点);
		//f_surface_计算包围盒(虚拟体网格);

		gIndirect单元素虚拟体_XY圆.firstVertex += offset;
		gIndirect单元素虚拟体_XZ圆.firstVertex += offset;
		gIndirect单元素虚拟体_圆柱.firstVertex += offset;
		gIndirect单元素虚拟体_平面.firstVertex += offset;



		{
			g虚拟体根物体 = f_ob_创建物体(*ctx, E_物体类型::t_包);
			
			S_MeshDrawProp Prop{};
			Prop.MeshPropOffset = g单元素虚拟体网格->m_网格元素属性.m_Mem.m_偏移;
			f_mesh_set绘制属性(g单元素虚拟体网格, Prop);
			

			f_ob_set数据槽数量(g虚拟体根物体, 1);
			f_ob_set数据(g虚拟体根物体, g单元素虚拟体网格, 0);
			f_ob_set材质(g虚拟体根物体, f_NodeCtx_get单元素虚拟体材质(*ctx), 0);
			//f_ob_set材质(g虚拟体根物体, f_NodeCtx_get逐顶点连续线材质(), 0);

			f_node_物体添加到主场景(g虚拟体根物体);
		}
	}
	return g虚拟体根物体;
}



void f_node_创建平行光虚拟体(S_物体* ob) {

	auto indirect = 中心Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(中心圆, indirect);

	indirect = 边界线_并排线Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(边界线, indirect);

	indirect = 方向Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(方向线, indirect);



	S_MeshTranformProp 线属性 = MeshProp_Init();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_mesh_set间接绘制网格属性(中心圆, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_GAZE;
	f_mesh_set间接绘制网格属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = 0;
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);




	S_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(中心圆, 中心圆Prop);
	S_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(边界线, 边界线Prop);
	S_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(方向线, 方向线Prop);
}

void f_node_创建点光源虚拟体(S_物体* ob) {
	
	auto indirect = 中心Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(中心圆, indirect);

	indirect = XYZ圆形Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(边界线, indirect);

	indirect = 方向Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(方向线, indirect);



	S_MeshTranformProp 线属性 = MeshProp_Init();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_mesh_set间接绘制网格属性(中心圆, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NONE;
	f_mesh_set间接绘制网格属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NONE;
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);


	S_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(中心圆, 中心圆Prop);
	S_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(边界线, 边界线Prop);
	S_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(方向线, 方向线Prop);
}

void f_node_创建聚光灯虚拟体(S_物体* ob) {
	
	auto indirect中心 = 中心Indirect;
	auto indirect边界 = XZ缩放圆形Indirect;
	auto indirect方向 = 锥形Indirect;
	f_node_设置聚光灯虚拟体绘制(indirect中心, indirect边界, indirect方向, ob->m_实例ID);
	f_surface_add间接绘制(中心圆, indirect中心);
	f_surface_add间接绘制(边界线, indirect边界);
	f_surface_add间接绘制(方向线, indirect方向);



	S_MeshTranformProp 线属性 = MeshProp_Init();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_mesh_set间接绘制网格属性(中心圆, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NONE;
	f_mesh_set间接绘制网格属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_GAZE;
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);



	S_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(中心圆, 中心圆Prop);
	S_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(边界线, 边界线Prop);
	S_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(方向线, 方向线Prop);

}

void f_node_创建区域光虚拟体(S_物体* ob) {

	auto indirect = 中心Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(中心圆, indirect);

	indirect = 四边Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(边界线, indirect);

	indirect = 方向Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(方向线, indirect);

	S_MeshTranformProp 线属性 = MeshProp_Init();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_mesh_set间接绘制网格属性(中心圆, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = 0;
	f_mesh_set间接绘制网格属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = 0;
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);


	S_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(中心圆, 中心圆Prop);
	S_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(边界线, 边界线Prop);
	S_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(方向线, 方向线Prop);
}


S_物体* f_node_创建摄像机虚拟体(S_物体* ob) {
	//return ob;
	auto indirect中心 = 中心_摄像机锥形Indirect;
	auto indirect边界 = 边界线_XY四边形Indirect;
	auto indirect方向 = 方向线_Y三角箭头_Indirect;
	
	//f_node_设置摄像机虚拟体绘制(indirect中心, indirect边界, indirect方向, g虚拟体主物体->m_变换矩阵.m_Mem.m_偏移);
	f_node_设置摄像机虚拟体绘制(indirect中心, indirect边界, indirect方向, 0);
	f_surface_add间接绘制(中心圆, indirect中心);
	f_surface_add间接绘制(边界线, indirect边界);
	f_surface_add间接绘制(方向线, indirect方向);
	ob->m_PickIndirect = indirect中心;


	S_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(中心圆, 中心圆Prop);
	S_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(边界线, 边界线Prop);
	S_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素属性.m_Mem.m_偏移;
	f_mesh_set绘制属性(方向线, 方向线Prop);

	S_MeshTranformProp 线属性 = MeshProp_Init();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	//线属性.m_TransformMode = 0;
	f_mesh_set间接绘制网格属性(中心圆, 线属性, ob->m_实例ID);
	f_mesh_set间接绘制网格属性(边界线, 线属性, ob->m_实例ID);
	
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_ZAxialZoom;
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);
	return ob;
}

void f_node_设置摄像机虚拟网格(S_物体* ob, S_摄像机* 摄像机) {
	//S_MeshTranformProp 线属性 = MeshProp_Init();
	S_MeshTranformProp 线属性 = f_buf_物体变换属性_at(中心圆->m_网格元素属性, ob->m_实例ID);

	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;
	线属性.m_TransformMode = 0;
	
	//f_mesh_set网格属性(f_ob_fromMesh(ob, 0), 线属性, ob->m_实例ID);
	vec3 s = f_camera_计算摄像机以角度缩放大小(摄像机);
	线属性.m_YScale = s.y;
	线属性.m_ZScale = s.z;
	
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_ZAxialZoom;

	f_buf_物体变换属性_at(边界线->m_网格元素属性, ob->m_实例ID).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_buf_物体变换属性_at(边界线->m_网格元素属性, ob->m_实例ID).m_YScale = s.y;
	f_buf_物体变换属性_at(边界线->m_网格元素属性, ob->m_实例ID).m_ZScale = s.z;

	f_buf_物体变换属性_at(中心圆->m_网格元素属性, ob->m_实例ID).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_ZAxialZoom;
	f_buf_物体变换属性_at(中心圆->m_网格元素属性, ob->m_实例ID).m_YScale = s.y;
	f_buf_物体变换属性_at(中心圆->m_网格元素属性, ob->m_实例ID).m_ZScale = s.z;

	f_buf_物体变换属性_at(方向线->m_网格元素属性, ob->m_实例ID).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_ZAxialZoom;
	f_buf_物体变换属性_at(方向线->m_网格元素属性, ob->m_实例ID).m_YScale = s.y;
	f_buf_物体变换属性_at(方向线->m_网格元素属性, ob->m_实例ID).m_ZScale = s.z;
	f_buf_物体变换属性_at(方向线->m_网格元素属性, ob->m_实例ID).m_YMove = s.y;

	
	f_mesh_set间接绘制网格属性(边界线, 线属性, ob->m_实例ID);
	f_mesh_set间接绘制网格属性(中心圆, 线属性, ob->m_实例ID);

	线属性.m_YMove = 线属性.m_YScale;
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);
}


void f_node_创建立方体虚拟体(S_物体* ob) {
	S_MeshTranformProp 线属性 = MeshProp_Init();

	auto indirect中心 = 中心_立方体Indirect;
	S_VkDrawIndirectCommand indirect边界 = {};
	S_VkDrawIndirectCommand indirect方向 = {};

	f_node_设置立方体虚拟体绘制(indirect中心, indirect边界, indirect方向, ob->m_实例ID);
	f_surface_add间接绘制(中心圆, indirect中心);
	f_surface_add间接绘制(边界线, indirect边界);
	f_surface_add间接绘制(方向线, indirect方向);
	ob->m_PickIndirect = indirect中心;


	线属性.m_TransformMode = 0;
	f_mesh_set间接绘制网格属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = 0;
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);
}

void f_node_设置立方体虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心_立方体Indirect;
	中心圆间接.firstInstance = offset;

	边界线间接 = {};
	方向线间接 = {};
}

void f_node_设置立方体虚拟网格(S_物体* ob, const vec3& size) {
	S_MeshTranformProp 线属性 = MeshProp_Init();

	线属性.m_XScale = size.x;
	线属性.m_YScale = size.y;
	线属性.m_ZScale = size.z;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;

	auto indirect中心 = 中心_立方体Indirect;
	S_VkDrawIndirectCommand indirect边界 = {};
	S_VkDrawIndirectCommand indirect方向 = {};

	f_node_设置立方体虚拟体绘制(indirect中心, indirect边界, indirect方向, ob->m_实例ID);
	ob->m_PickIndirect = 中心_立方体Indirect;

	f_surface_set间接绘制区间(中心圆, indirect中心, ob->m_实例ID);
	f_surface_set间接绘制区间(边界线, indirect边界, ob->m_实例ID);
	f_surface_set间接绘制区间(方向线, indirect方向, ob->m_实例ID);

	//f_material_set线属性(f_NodeCtx_get灯光模型中心圆材质(中心圆->m_Ctx), ob->m_实例ID, 线属性);
	//f_material_set线属性(f_NodeCtx_get灯光模型范围线材质(边界线->m_Ctx), ob->m_实例ID, 线属性);
	//f_material_set线属性(f_NodeCtx_get灯光模型方向线材质(方向线->m_Ctx), ob->m_实例ID, 线属性);
	f_mesh_set间接绘制网格属性(中心圆, 线属性, ob->m_实例ID);
	f_mesh_set间接绘制网格属性(边界线, 线属性, ob->m_实例ID);
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);
}

void f_node_设置球体虚拟网格(S_物体* ob, const vec3& size) {
	S_MeshTranformProp 线属性 = MeshProp_Init();

	线属性.m_XScale = size.x;
	线属性.m_YScale = size.y;
	线属性.m_ZScale = size.z;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;

	f_surface_set间接绘制区间(中心圆, XYZ圆形Indirect, ob->m_实例ID);
	f_surface_set间接绘制区间(边界线, {}, ob->m_实例ID);
	f_surface_set间接绘制区间(方向线, {}, ob->m_实例ID);

	f_mesh_set间接绘制网格属性(中心圆, 线属性, ob->m_实例ID);
	f_mesh_set间接绘制网格属性(边界线, 线属性, ob->m_实例ID);
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);
}

void f_node_设置链接线方体虚拟网格(S_物体* ob, const vec3& size, const vec3& loc) {
	S_MeshTranformProp 线属性 = MeshProp_Init();

	线属性 = f_buf_物体变换属性_at(中心圆->m_网格元素属性, ob->m_实例ID);
	线属性.m_XScale = size.x;
	线属性.m_YScale = size.y;
	线属性.m_ZScale = size.z;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;
	f_mesh_set间接绘制网格属性(中心圆, 线属性, ob->m_实例ID);


	线属性 = f_buf_物体变换属性_at(方向线->m_网格元素属性, ob->m_实例ID);
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;
	线属性.m_XMove = loc.x;
	线属性.m_YMove = loc.y;
	线属性.m_ZMove = loc.z;
	//线属性.m_DottedLine;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_PointLink;
	f_mesh_set间接绘制网格属性(方向线, 线属性, ob->m_实例ID);


	f_surface_set间接绘制区间(中心圆, 中心_立方体Indirect, ob->m_实例ID);
	f_surface_set间接绘制区间(边界线, {}, ob->m_实例ID);
	f_surface_set间接绘制区间(方向线, 方向线_链接线_Indirect, ob->m_实例ID);
	
}


void f_node_移除虚拟体(S_物体* ob) {
	uint32 num = g虚拟体主物体->m_子物体.size();
	auto* data = g虚拟体主物体->m_子物体.data();

	f_buf_at_Indirect(*中心圆->m_间接, ob->m_实例ID).instanceCount = 0;
	f_buf_at_Indirect(*边界线->m_间接, ob->m_实例ID).instanceCount = 0;
	f_buf_at_Indirect(*方向线->m_间接, ob->m_实例ID).instanceCount = 0;

	ob->m_渲染 = false;
	ob->m_销毁 = true;
	
	for (uint32 i = 0; i < num; ++i) {
		if (data[i] == ob) {
			g虚拟体主物体->m_子物体.erase(g虚拟体主物体->m_子物体.begin() + i);
			f_surface_mov绘制区间(中心圆, i);
			f_surface_mov绘制区间(边界线, i);
			f_surface_mov绘制区间(方向线, i);
			break;
		}
	}
	
	//return;
	if(!中心圆->m_间接->m_Mem.m_大小 || !边界线->m_间接->m_Mem.m_大小 || !方向线->m_间接->m_Mem.m_大小) return;

	num = g虚拟体主物体->m_子物体.size();
	data = g虚拟体主物体->m_子物体.data();

	auto* 中心圆indirect = f_buf_Indirect_ptr(*中心圆->m_间接);
	auto* 边界线indirect = f_buf_Indirect_ptr(*边界线->m_间接);
	auto* 方向线indirect = f_buf_Indirect_ptr(*方向线->m_间接);
	for (uint32 i = 0; i < num; ++i) {
		data[i]->m_实例ID = i;

		switch (data[i]->m_Type) {
		case E_物体类型::t_点光源: {
			f_node_设置点光源虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			break;
		}
		case E_物体类型::t_聚光灯: {
			f_node_设置聚光灯虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			break;
		}
		case E_物体类型::t_区域光_圆形: {
			f_node_设置圆形区域光虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			break;
		}
		case E_物体类型::t_区域光_方形: {
			f_node_设置方形区域光虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			break;
		}
		case E_物体类型::t_虚拟体: {
			f_node_设置摄像机虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			data[i]->m_PickIndirect = 中心圆indirect[i];
			break;
		}
		}
	}
}

void f_node_设置灯光虚拟网格类型(S_物体* ob, E_物体类型 类型) {
	switch (类型) {
	case E_物体类型::t_区域光_方形: {
		auto indirect = 四边Indirect;
		indirect.firstInstance = ob->m_实例ID;

		f_surface_set间接绘制区间(边界线, indirect, ob->m_实例ID);
		break;
	}
	case E_物体类型::t_区域光_圆形: {
		auto indirect = XZ圆形Indirect;
		indirect.firstInstance = ob->m_实例ID;
		f_surface_set间接绘制区间(边界线, indirect, ob->m_实例ID);
		break;
	}
	default:
		break;
	}
}

void f_node_设置灯光虚拟网格范围(S_物体* ob, const vec2& r) {
	switch (ob->m_Type) {
	case E_物体类型::t_聚光灯: {
		S_MeshTranformProp 线属性 = MeshProp_Init();
		线属性.m_Remote = 1;
		线属性.m_Scale = r.y;
		线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_GAZE;

		f_buf_物体变换属性_at(方向线->m_网格元素属性, ob->m_实例ID).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_GAZE;
		f_buf_物体变换属性_at(方向线->m_网格元素属性, ob->m_实例ID).m_Scale = r.y;
		//f_mesh_set网格属性(方向线, 线属性, ob->m_实例ID);
		break;
	}
	case E_物体类型::t_区域光_方形: {
		
		break;
	}
	case E_物体类型::t_区域光_圆形: {
		
		break;
	}
	}
}

void f_node_设置点光源虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心Indirect;
	中心圆间接.firstInstance = offset;
	
	边界线间接 = XYZ圆形Indirect;
	边界线间接.firstInstance = offset;

	方向线间接 = 方向Indirect;
	方向线间接.firstInstance = offset;
}

void f_node_设置聚光灯虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心Indirect;
	中心圆间接.firstInstance = offset;

	边界线间接 = XZ缩放圆形Indirect;
	边界线间接.firstInstance = offset;

	方向线间接 = 锥形Indirect;
	方向线间接.firstInstance = offset;
}

void f_node_设置方形区域光虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心Indirect;
	中心圆间接.firstInstance = offset;

	边界线间接 = 四边Indirect;
	边界线间接.firstInstance = offset;

	方向线间接 = 方向Indirect;
	方向线间接.firstInstance = offset;
}

void f_node_设置圆形区域光虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心Indirect;
	中心圆间接.firstInstance = offset;

	边界线间接 = XZ圆形Indirect;
	边界线间接.firstInstance = offset;

	方向线间接 = 方向Indirect;
	方向线间接.firstInstance = offset;
}

void f_node_设置摄像机虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心_摄像机锥形Indirect;
	中心圆间接.firstInstance = offset;
	
	边界线间接 = 边界线_XY四边形Indirect;
	边界线间接.firstInstance = offset;
	边界线间接.instanceCount = 0;

	方向线间接 = 方向线_Y三角箭头_Indirect;
	方向线间接.firstInstance = offset;
}






S_物体* f_node_创建UV辅助操作虚拟体(S_设备环境& ctx) {
	//static S_物体* gUV辅助操作虚拟体 = f_ob_创建物体(ctx, E_物体类型::t_虚拟体);
	auto* 虚拟体根物体 = f_node_get单元素虚拟体根物体(&ctx);
	
	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_虚拟体);
	S_Mesh* me = f_surface_创建实例(g单元素虚拟体网格);
	f_ob_set数据槽数量(ob, 1);
	f_ob_set数据(ob, me);
	//f_buf_push_back<Mat44f>(虚拟体根物体->m_变换矩阵, { {} });
	f_ob_add实例物体(虚拟体根物体, ob);


	f_surface_计算包围盒(me, gIndirect单元素虚拟体_圆柱.firstVertex, gIndirect单元素虚拟体_圆柱.vertexCount);


	auto indirect = gIndirect单元素虚拟体_圆柱;
	indirect.firstInstance = ob->m_变换ID;
	me->m_间接绘制偏移 = f_surface_add间接绘制(g单元素虚拟体网格, indirect);
	me->m_间接绘制数量 = 1;

	f_material_add线属性(f_NodeCtx_get单元素虚拟体材质(ctx), 1);
	S_MeshTranformProp 线属性 = MeshProp_Init();
	//f_material_set线属性(f_NodeCtx_get单元素虚拟体材质(ctx), ob->m_实例ID, 线属性);
	f_mesh_set间接绘制网格属性(g单元素虚拟体网格, 线属性, ob->m_实例ID);
	return ob;
}

void f_node_设置UV操作虚拟体类型(S_物体* ob, uint32 type) {
	switch (type) {
	case 0: {
		auto indirect = gIndirect单元素虚拟体_平面;
		indirect.firstInstance = ob->m_变换ID;
		f_surface_set间接绘制区间(g单元素虚拟体网格, indirect, ob->m_实例ID);
		S_MeshTranformProp 线属性 = MeshProp_Init();
		//f_material_set线属性(f_NodeCtx_get单元素虚拟体材质(g单元素虚拟体网格->m_Ctx), ob->m_实例ID, 线属性);
		f_mesh_set间接绘制网格属性(g单元素虚拟体网格, 线属性, ob->m_实例ID);
		break;
	}
	case 1: {
	//	break;
	}
	case 2: {
	//	break;
	}
	case 3: {
		auto indirect = gIndirect单元素虚拟体_圆柱;
		indirect.firstInstance = ob->m_变换ID;
		f_surface_set间接绘制区间(g单元素虚拟体网格, indirect, ob->m_实例ID);
		S_MeshTranformProp 线属性 = MeshProp_Init();
		//f_material_set线属性(f_NodeCtx_get单元素虚拟体材质(g单元素虚拟体网格->m_Ctx), ob->m_实例ID, 线属性);
		f_mesh_set间接绘制网格属性(g单元素虚拟体网格, 线属性, ob->m_实例ID);
		break;
	}
	default:
		break;
	}
}

S_物体* f_node_创建单元素虚拟体(S_设备环境& ctx) {
	auto* 虚拟体根物体 = f_node_get多元素虚拟体根物体(ctx);

	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_虚拟体);
	f_ob_add子物体(虚拟体根物体, ob);
	f_buf_push_back<Mat44f>(虚拟体根物体->m_变换矩阵, { {} });
	f_ob_set数据槽数量(虚拟体根物体, 3);


	//f_mesh_add网格属性(g虚拟体中心圆, 1);
	//f_mesh_add网格属性(g虚拟体边界线, 1);
	//f_mesh_add网格属性(g虚拟体方向线, 1);
	//f_material_add线属性(f_NodeCtx_get虚拟体中心圆材质(g虚拟体中心圆->m_Ctx), 1);
	//f_material_add线属性(f_NodeCtx_get虚拟体范围线材质(g虚拟体边界线->m_Ctx), 1);
	//f_material_add线属性(f_NodeCtx_get虚拟体方向线材质(g虚拟体方向线->m_Ctx), 1);


	auto indirect = g虚拟体中心Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(g虚拟体中心圆, indirect);

	indirect = g虚拟体边界线_并排线Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(g虚拟体边界线, indirect);

	indirect = g虚拟体方向Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(g虚拟体方向线, indirect);

	return ob;
}
void f_node_设置单元素虚拟体类型(S_物体* ob, uint32 type) {

}

S_物体* f_node_创建圆柱UV辅助操作虚拟体(S_设备环境& ctx) {
	S_物体* m_Ob = f_ob_创建物体(ctx, E_物体类型::t_虚拟体);
	f_ob_add子物体(g虚拟体主物体, m_Ob);
	f_buf_push_back<Mat44f>(g虚拟体主物体->m_变换矩阵, { {} });
	
	//f_mesh_add网格属性(g虚拟体中心圆, 1);
	//f_mesh_add网格属性(g虚拟体边界线, 1);
	//f_mesh_add网格属性(g虚拟体方向线, 1);
	//f_material_add线属性(f_NodeCtx_get灯光模型中心圆材质(中心圆->m_Ctx), 1);
	//f_material_add线属性(f_NodeCtx_get灯光模型范围线材质(边界线->m_Ctx), 1);
	//f_material_add线属性(f_NodeCtx_get灯光模型方向线材质(方向线->m_Ctx), 1);

	S_MeshTranformProp 线属性 = MeshProp_Init();
	


	auto indirect = 中心Indirect;
	indirect.firstInstance = m_Ob->m_实例ID;
	f_surface_add间接绘制(中心圆, indirect);

	indirect = 边界线_并排线Indirect;
	indirect.firstInstance = m_Ob->m_实例ID;
	f_surface_add间接绘制(边界线, indirect);

	indirect = 方向Indirect;
	indirect.firstInstance = m_Ob->m_实例ID;
	f_surface_add间接绘制(方向线, indirect);

	return m_Ob;
}







void f_node_物体加入全局容器中(S_物体* ob) {
	if (S_节点数据::g_全局索引物体.find(ob->m_Name) != S_节点数据::g_全局索引物体.end()) {
		ob->m_Name = S_节点数据::g_物体名称分配器.f_Gen(ob->m_Name);
	}
	S_节点数据::g_全局索引物体[ob->m_Name] = ob;
	f_OE_创建可编辑物体属性(ob);

	for(auto& e : ob->m_子物体) f_node_物体加入全局容器中(e);
}

void f_node_物体从全局容器移除(S_物体* ob) {
	if (S_节点数据::g_全局索引物体.find(ob->m_Name) != S_节点数据::g_全局索引物体.end()) {
		S_节点数据::g_全局索引物体.erase(ob->m_Name);
		S_节点数据::g_物体名称分配器.f_Move(ob->m_Name);

		for(auto& e : ob->m_子物体) f_node_物体从全局容器移除(e);
	}
}

S_物体* f_node_从全局物体容器查找物体(std::wstring name) {
	if (S_节点数据::g_全局索引物体.find(name) != S_节点数据::g_全局索引物体.end()) {
		return S_节点数据::g_全局索引物体[name];
	}
	return nullptr;
}

S_单色材质包 f_node_get骨骼可视材质(S_设备环境& ctx) {
	S_单色材质包 包;

	if (g_骨骼材质包.size()) {
		包 = g_骨骼材质包.back();
		g_骨骼材质包.pop_back();
	}
	else {
		static S_单色材质包 m = {
			new S_独立缩放单色材质(ctx, E_绘制方式::e_三角形, E_填充模式::e_填充线, true, true, true),
			new S_独立缩放单色材质(ctx, E_绘制方式::e_三角形, E_填充模式::e_填充面, true, true, true),
			new S_独立缩放单色材质(ctx, E_绘制方式::e_三角形, E_填充模式::e_填充线, true, true, true),
		};

		包.m_描边 = (S_单色材质*)m.m_描边->f_copy();
		包.m_面 = (S_单色材质*)m.m_面->f_copy();
		包.m_线 = (S_单色材质*)m.m_线->f_copy();
		//包.m_面->f_set颜色({127,127,127,127});
	}
	
	return 包;
}

void f_node_回收骨骼可视材质(S_单色材质包 包) {
	g_骨骼材质包.push_back(包);
}





S_材质* f_node_getVecSphere材质(S_设备环境& ctx) {
	S_材质* 材质 = new S_VecSphere可视预览材质(ctx);

	if (g_VecSphere质包.size()) {
		材质 = g_VecSphere质包.back();
		g_VecSphere质包.pop_back();
	}
	else {
		材质 = new S_VecSphere可视预览材质(ctx);
	}

	return 材质;
}

void f_node_回收VecSphere可视材质(S_材质* 材质) {
	g_VecSphere质包.push_back(材质);
}

S_骨骼插座数据* f_node_创建编辑骨骼() {
	S_骨骼插座数据* b = new S_骨骼插座数据;
	(*b) = {};
	b->m_骨架 = new S_物体(E_物体类型::t_骨骼);
	b->m_骨节 = new S_物体(E_物体类型::t_实例);
	return b;
}


static std::mutex g要删除物体内存锁;
static std::vector<S_物体*> g要删除物体;
void f_node_创建物体(S_OBArray* obs) {

}

void f_node_删除物体(S_OBArray* obs) {
	g要删除物体内存锁.lock();

	f_node_从主场景移除物体(obs);
	for (uint32 i=0; i<obs->count; ++i) {
		if (obs->ptr_userData[i]) {
			obs->ptr_userData[i]->m_销毁 = true;
			g要删除物体.push_back(obs->ptr_userData[i]);
		}
	}

	g要删除物体内存锁.unlock();

	f_core_array_resize((S_Array*)obs, 0);
}

void f_node_删除物体(std::vector<S_物体*>& obs) {
	g要删除物体内存锁.lock();

	f_node_从主场景移除物体(obs);
	for (auto& ob : obs) {
		ob->m_销毁 = true;
		g要删除物体.push_back(ob);
	}

	g要删除物体内存锁.unlock();

	obs.clear();
}

bool f_node_销毁物体() {
	if (g要删除物体.size()) {
		g要删除物体内存锁.lock();

		for (auto& e : g要删除物体) {
			switch (e->m_Type) {
			case E_物体类型::t_网格: {
				f_surface_释放网格(f_ob_fromMesh(e, 0));
				break;
			}
			case E_物体类型::t_多边形: {
				for (uint32 j = 0; j < e->m_DataNum; ++j) {
					f_surface_释放网格(f_ob_fromMesh(e, j));
				}
				break;
			}
			}
			f_ob_销毁物体(e);
		}
		g要删除物体.clear();

		g要删除物体内存锁.unlock();
		return true;
	}
	
	return false;
}








//void f_node_物体节点创建物体数据(S_物体* ob) {
//	f_ob_set数据槽数量(ob, 3);
//
//	S_Mesh* mesh = (S_Mesh*)(ob->m_Data[0]);
//	S_Mesh* m1 = f_surface_创建实例(mesh);
//	S_Mesh* m2 = f_surface_创建实例(mesh);
//
//	f_ob_set数据(ob, m1, 1);
//	f_ob_set数据(ob, m2, 2);
//
//	f_ob_set材质(ob, f_NodeCtx_get基本光照描边材质(), 0);
//	f_ob_set材质(ob, f_NodeCtx_get基本光照面材质(), 1);
//	f_ob_set材质(ob, f_NodeCtx_get基本光照线材质(), 2);
//
//
//	f_mesh_add网格属性(mesh, 1);
//	f_mesh_add网格属性(m1, 1);
//	f_mesh_add网格属性(m2, 1);
//
//	auto 网格属性 = MeshProp_Init();
//	网格属性.m_Activate = 1;
//	f_mesh_set网格属性(mesh, 网格属性);
//
//	f_node_网格绘制属性设置(ob);
//
//
//	ob->m_Name = L"物体节点创建物体";
//}





